﻿-- ********************************************************************************
-- Lazy Transform
-- Automates the process of milling, prospecting and disenchanting.
-- By: Shenton
--
-- Config.lua
-- ********************************************************************************

local A = _G["LazyTransformGlobal"];
local L = A.L;

-- ********************************************************************************
-- Global to local
-- ********************************************************************************

-- LUA
local format = format;
local pairs = pairs;
local table = table;
local tostring = tostring;
local ipairs = ipairs;
local type = type;
local tonumber = tonumber;
local string = string;

-- WoW
local tContains = tContains;
local GetItemInfo = GetItemInfo;
local GetBagName = GetBagName;
local NUM_BAG_FRAMES = NUM_BAG_FRAMES;
local UIParent = UIParent;
local strsplit = strsplit;

-- Others
local LibStub = LibStub;

-- ********************************************************************************
-- Configuration DB
-- ********************************************************************************

--- Default configuration table for AceDB
A.defaultDB =
{
    profile =
    {
        checkMailFrame = 1,
        button =
        {
            hide = nil,
            lock = nil,
            point =
            {
                point = "CENTER",
                relativeTo = UIParent,
                relativePoint = "CENTER",
                offX = 0,
                offY = 0,
            },
        },
        milling =
        {
            enabled = nil,
            ignore = {},
        },
        prospect =
        {
            enabled = nil,
            rareOre = nil,
            ignore = {},
        },
        disenchant =
        {
            enabled = nil,
            bags =
            {
                ["0"] = nil,
                ["1"] = nil,
                ["2"] = nil,
                ["3"] = nil,
                ["4"] = nil,
            },
            soulbound = nil,
            threshold = 2,
            ignore = {},
        },
        minimap =
        {
            hide = nil,
        },
    },
};

-- ********************************************************************************
-- Configuration Panel
-- ********************************************************************************

local disenchantRemoveToggle = {};

function A:ConfigurationPanel()
    local panel =
    {
        name = L["Lazy Transform"],
        type = "group",
        childGroups = "tab",
        args =
        {
            options =
            {
                order = 0,
                name = L["Options"],
                type = "group",
                args =
                {
                    common =
                    {
                        order = 0,
                        name = L["Common"],
                        type = "group",
                        inline = true,
                        args =
                        {
                            show =
                            {
                                order = 0,
                                name = L["Check mail frame"],
                                desc = L["Check if the mail window is open when processing."],
                                type = "toggle",
                                set = function() A.db.profile.checkMailFrame = not A.db.profile.checkMailFrame; end,
                                get = function() return A.db.profile.checkMailFrame; end,
                            },
                        },
                    },
                    button =
                    {
                        order = 10,
                        name = L["Button"],
                        type = "group",
                        inline = true,
                        args =
                        {
                            show =
                            {
                                order = 0,
                                name = L["Show"],
                                desc = L["Show the process button."],
                                type = "toggle",
                                set = function() A:ToggleButtonHideShow(); end,
                                get = function() return not A.db.profile.button.hide; end,
                            },
                            lock =
                            {
                                order = 1,
                                name = L["Lock"],
                                desc = L["Lock the process button."],
                                type = "toggle",
                                set = function() A:ToggleButtonLock(); end,
                                get = function() return A.db.profile.button.lock; end,
                            },
                            reset =
                            {
                                order = 2,
                                name = L["Reset"],
                                desc = L["Reset the button position to the center of the screen."],
                                type = "execute",
                                func = function()
                                    A.db.profile.button.point.point = "CENTER";
                                    A.db.profile.button.point.relativeTo = UIParent;
                                    A.db.profile.button.point.relativePoint = "CENTER";
                                    A.db.profile.button.point.offX = 0;
                                    A.db.profile.button.point.offY = 0;

                                    A:SetButtonPos();
                                end,
                            },
                        },
                    },
                    minimap =
                    {
                        order = 20,
                        name = L["Minimap"],
                        type = "group",
                        inline = true,
                        args =
                        {
                            show =
                            {
                                order = 0,
                                name = L["Show"],
                                desc = L["Show the minimap icon."],
                                type = "toggle",
                                set = function()
                                    A.db.profile.minimap.hide = not A.db.profile.minimap.hide;
                                    A:ShowHideMinimap();
                                end,
                                get = function() return not A.db.profile.minimap.hide; end,
                            },
                        },
                    },
                },
            },
            disenchant =
            {
                order = 10,
                name = L["Disenchant"],
                type = "group",
                args =
                {
                    enabled =
                    {
                        order = 0,
                        name = L["Enabled"],
                        desc = L["Enable %s."]:format(L["Disenchant"]),
                        type = "toggle",
                        set = function() A.db.profile.disenchant.enabled = not A.db.profile.disenchant.enabled; end,
                        get = function() return A.db.profile.disenchant.enabled; end,
                    },
                    options =
                    {
                        order = 10,
                        name = L["Options"],
                        type = "group",
                        inline = true,
                        disabled = not A.db.profile.disenchant.enabled,
                        args =
                        {
                            soulbound =
                            {
                                order = 0,
                                name = L["Soulbound"],
                                desc = L["Enable disenchant for soulbound items."],
                                type = "toggle",
                                set = function() A.db.profile.disenchant.soulbound = not A.db.profile.disenchant.soulbound; end,
                                get = function() return A.db.profile.disenchant.soulbound; end,
                            },
                            qualityThreshold =
                            {
                                order = 2,
                                name = L["Quality threshold"],
                                desc = L["Choose at which maximum quality threshold it should search for items to disenchant."],
                                type = "select",
                                values = { [2] = "|cff1eff00"..L["Uncommon"], [3] = "|cff0070dd"..L["Rare"], [4] = "|cffa335ee"..L["Epic"], },
                                set = function(info, val) A.db.profile.disenchant.threshold = val; end,
                                get = function() return A.db.profile.disenchant.threshold; end,
                            },
                            bags =
                            {
                                order = 10,
                                name = L["Bags"],
                                type = "group",
                                inline = true,
                                args = {},
                            },
                        },
                    },
                    ignore =
                    {
                        order = 20,
                        name = L["Ignore"],
                        type = "group",
                        inline = true,
                        disabled = not A.db.profile.disenchant.enabled,
                        args =
                        {
                            add =
                            {
                                order = 0,
                                name = L["Add"],
                                type = "group",
                                inline = true,
                                args =
                                {
                                    input =
                                    {
                                        order = 0,
                                        name = L["Item"],
                                        desc = L["Add here an item ID or an item link (Shift+Click)."],
                                        type = "input",
                                        width = "full",
                                        set = function(info, val) A.disenchantIgnoreInput = val; end,
                                    },
                                    header1 =
                                    {
                                        order = 1,
                                        name = "",
                                        type = "header",
                                    },
                                    desc =
                                    {
                                        order = 2,
                                        name = function()
                                            local _, itemLink;

                                            if ( not A.disenchantIgnoreInput or A.disenchantIgnoreInput == "" ) then
                                                return L["No item selected."];
                                            else
                                                if ( type(A.disenchantIgnoreInput) == "number" or tonumber(A.disenchantIgnoreInput) ) then
                                                    _, itemLink = GetItemInfo(A.disenchantIgnoreInput);
                                                else
                                                    local itemString = string.match(A.disenchantIgnoreInput, "item[%-?%d:]+");

                                                    if ( itemString ) then itemLink = A.disenchantIgnoreInput; end
                                                end

                                                if ( itemLink ) then
                                                    return itemLink;
                                                else
                                                    A.disenchantIgnoreInput = nil;
                                                    return L["Item not found."];
                                                end
                                            end
                                        end,
                                        type = "description",
                                        width = "full",
                                    },
                                    header2 =
                                    {
                                        order = 3,
                                        name = "",
                                        type = "header",
                                    },
                                    exec =
                                    {
                                        order = 4,
                                        name = L["Add"],
                                        desc = L["Add the item to ignore list."],
                                        type = "execute",
                                        disabled = not A.disenchantIgnoreInput,
                                        func = function()
                                            if ( not A.disenchantIgnoreInput or A.disenchantIgnoreInput == "" ) then return; end

                                            local _, itemID;

                                            if ( type(A.disenchantIgnoreInput) == "number" or tonumber(A.disenchantIgnoreInput) ) then
                                                itemID = tonumber(A.disenchantIgnoreInput);
                                            else
                                                local itemString = string.match(A.disenchantIgnoreInput, "item[%-?%d:]+");
                                                _, itemID = strsplit(":", itemString);
                                            end

                                            if ( itemID and GetItemInfo(tonumber(itemID)) ) then
                                                A.db.profile.disenchant.ignore[#A.db.profile.disenchant.ignore+1] = tonumber(itemID);
                                            end

                                            A.disenchantIgnoreInput = nil;
                                        end,
                                    },
                                },
                            },
                            list =
                            {
                                order = 10,
                                name = L["List"],
                                type = "group",
                                inline = true,
                                args = {},
                            },
                        },
                    },
                },
            },
            milling =
            {
                order = 20,
                name = L["Milling"],
                type = "group",
                args =
                {
                    enabled =
                    {
                        order = 0,
                        name = L["Enabled"],
                        desc = L["Enable %s."]:format(L["Milling"]),
                        type = "toggle",
                        set = function() A.db.profile.milling.enabled = not A.db.profile.milling.enabled; end,
                        get = function() return A.db.profile.milling.enabled; end,
                    },
                    ignore =
                    {
                        order = 10,
                        name = L["Ignore"],
                        type = "group",
                        inline = true,
                        disabled = not A.db.profile.milling.enabled,
                        args = {},
                    },
                },
            },
            prospect =
            {
                order = 30,
                name = L["Prospect"],
                type = "group",
                args =
                {
                    enabled =
                    {
                        order = 0,
                        name = L["Enabled"],
                        desc = L["Enable %s."]:format(L["Prospect"]),
                        type = "toggle",
                        set = function() A.db.profile.prospect.enabled = not A.db.profile.prospect.enabled; end,
                        get = function() return A.db.profile.prospect.enabled; end,
                    },
                    options =
                    {
                        order = 10,
                        name = L["Options"],
                        type = "group",
                        inline = true,
                        disabled = not A.db.profile.prospect.enabled,
                        args =
                        {
                            rareOres =
                            {
                                order = 0,
                                name = L["Rare ores"],
                                desc = L["Enable rare ores in the process, the green ones."],
                                type = "toggle",
                                set = function() A.db.profile.prospect.rareOre = not A.db.profile.prospect.rareOre; end,
                                get = function() return A.db.profile.prospect.rareOre; end,
                            },
                        },
                    },
                    ignore =
                    {
                        order = 20,
                        name = L["Ignore"],
                        type = "group",
                        inline = true,
                        disabled = not A.db.profile.prospect.enabled,
                        args = {},
                    },
                },
            },
        },
    };

    local order = 0;
    for i=0,NUM_BAG_FRAMES do
        local bagName = GetBagName(i).." ("..i..")";

        panel.args.disenchant.args.options.args.bags.args[tostring(i)] =
        {
            order = order,
            name = bagName,
            desc = L["Enable searching for items to disenchant in bag %s."]:format(bagName),
            type = "toggle",
            width = "full",
            set = function() A.db.profile.disenchant.bags[tostring(i)] = not A.db.profile.disenchant.bags[tostring(i)]; end,
            get = function() return A.db.profile.disenchant.bags[tostring(i)]; end,
        };

        order = order + 1;
    end

    order = 0;
    for k,v in pairs(A.herbs) do
        local itemName = GetItemInfo(k);

        panel.args.milling.args.ignore.args[itemName] =
        {
            order = order,
            name = itemName.." ("..v..")",
            desc = L["Ignore %s."]:format(itemName),
            type = "toggle",
            set = function(info, val)
                if ( val ) then
                    if ( not tContains(A.db.profile.milling.ignore, k) ) then
                        A.db.profile.milling.ignore[#A.db.profile.milling.ignore+1] = k;
                    end
                else
                    if ( tContains(A.db.profile.milling.ignore, k) ) then
                        local pos = A:GetItemPos(A.db.profile.milling.ignore, k);

                        table.remove(A.db.profile.milling.ignore, pos);
                    end
                end
            end,
            get = function()
                if ( tContains(A.db.profile.milling.ignore, k) ) then return 1; end

                return nil;
            end,
        };
    end

    order = 0;
    for k,v in pairs(A.ores) do
        local itemName = GetItemInfo(k);

        panel.args.prospect.args.ignore.args[itemName] =
        {
            order = order,
            name = itemName.." ("..v..")",
            desc = L["Ignore %s."]:format(itemName),
            type = "toggle",
            set = function(info, val)
                if ( val ) then
                    if ( not tContains(A.db.profile.prospect.ignore, k) ) then
                        A.db.profile.prospect.ignore[#A.db.profile.prospect.ignore+1] = k;
                    end
                else
                    if ( tContains(A.db.profile.prospect.ignore, k) ) then
                        local pos = A:GetItemPos(A.db.profile.prospect.ignore, k);

                        table.remove(A.db.profile.prospect.ignore, pos);
                    end
                end
            end,
            get = function()
                if ( tContains(A.db.profile.prospect.ignore, k) ) then return 1; end

                return nil;
            end,
        };
    end

    order = 0;
    for k,v in ipairs(A.db.profile.disenchant.ignore) do
        local itemName, itemLink, _, _, _, _, _, _, _, itemTexture = GetItemInfo(v);

        panel.args.disenchant.args.ignore.args.list.args[itemName] =
        {
            order = order,
            name = itemName,
            type = "group",
            inline = true,
            args =
            {
                itemLink =
                {
                    order = 0,
                    name = itemLink,
                    image = itemTexture,
                    type = "description",
                    width = "full",
                },
                header =
                {
                    order = 1,
                    name = "",
                    type = "header",
                },
                removeToggle =
                {
                    order = 2,
                    name = L["Enable"],
                    desc = L["Enable the Remove button."],
                    type = "toggle",
                    get = disenchantRemoveToggle[itemName],
                    set = function() disenchantRemoveToggle[itemName] = not disenchantRemoveToggle[itemName]; end,
                },
                removeExecute =
                {
                    order = 3,
                    name = L["Remove"],
                    desc = L["Remove %s from ignore list."]:format(itemName),
                    type = "execute",
                    disabled = not disenchantRemoveToggle[itemName],
                    func = function()
                        local pos = A:GetItemPos(A.db.profile.disenchant.ignore, v);

                        table.remove(A.db.profile.disenchant.ignore, pos);
                    end,
                },
            },
        };

        order = order + 1;
    end

    -- Profiles
    panel.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(A.db);
    panel.args.profile.order = 1000;

    return panel;
end
